package com.jdd.modules.sdk.sdkidentifycallbackresults;

import com.jdd.common.api.vo.ResultVo;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.util.*;
import com.jdd.modules.parking.entity.ParkArmInfo;
import com.jdd.modules.parking.service.IParkArmInfoService;
import com.jdd.modules.sdk.config.CameraSdk;
import com.jdd.modules.sdk.utils.Callback_FGetImageCBEx;
import com.jdd.modules.sdk.utils.IPAndInt;
import com.jdd.modules.sdk.utils.QIANYISDK;
import com.jdd.modules.sdk.utils.StatusCode;
import com.jdd.modules.sdkidentifyresultpushlog.entity.SdkIdentifyResultPushLog;
import com.jdd.modules.sdkidentifyresultpushlog.service.ISdkIdentifyResultPushLogService;
import com.jdd.modules.sdkidentifyresultpushlog.service.ISdkIdentifyResultPushLogV3Service;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Random;

/**
 * @version 1.0
 * @Description:
 * @author： jdd尚岳
 * @Date: 2021-08-06 16:01
 */
@Component
@Slf4j
public class QianYiSdkIdentifyCallbackResults implements Callback_FGetImageCBEx.FGetImageCBEx{
    @Resource
    private ISdkIdentifyResultPushLogService sdkIdentifyResultPushLogService;
    @Resource
    private IParkArmInfoService parkArmInfoService;
    @Value("${uploadImages.location}")
    private String imageLocation;
    @Value("${uploadFile.location}")
    private String location;
    @Resource
    private CacheUtil cacheUtil;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private CameraSdk cameraSdk;

    public String appScrect;

    public String appId;
    @Resource
    private RestTemplateUtils restTemplateUtils;
    @Resource
    private ISdkIdentifyResultPushLogV3Service sdkIdentifyResultPushLogV3Service;
    @Resource
    AsynRestTmplateUtils asynRestTmplateUtils;
    @Value("${oss.domain.name}")
    private String ossDomainName;
    @Override
    public int invoke(int tHandle, int uiImageId, QIANYISDK.T_ImageUserInfo.ByReference ptImageInfo, QIANYISDK.T_PicInfo.ByReference ptPicInfo, Pointer paramPointer) {
        QIANYISDK qianYiSdk = cameraSdk.getQianYiSdk();
        try {
           /* //防止重复识别
            if (ptImageInfo.ucSnapType == 1) {
                return 0;
            }*/

            //拿到当前闸机的ip
            QIANYISDK.T_NetSetup.ByReference ptNetSetup = new QIANYISDK.T_NetSetup.ByReference();
            int qns = qianYiSdk.Net_QueryNETSetup(tHandle, ptNetSetup);
            //查询IP的返回结果
            log.info(StatusCode.getStatusCode(qns, "Net_QueryNETSetup"));
            //拿到的具体ip
            String ip = IPAndInt.intToIp(ptNetSetup.uiIPAddress);
            //通过ip拿到闸机序列号，然后会通过序列号拿到拿到场端code
            ParkArmInfo parkArmInfo = parkArmInfoService.findParkArmInfoByIp(ip);
            if (null==parkArmInfo){
                return 0;
            }

            //车牌号
            String license = new String(ptImageInfo.szLprResult, "GBK");
            log.info(license.trim());

            //组装识别信息
            SdkIdentifyResultPushLog sdkIdentifyResultPushLog = new SdkIdentifyResultPushLog();
            sdkIdentifyResultPushLog.setId(SnowFlakeUtil.getId());
            sdkIdentifyResultPushLog.setIpAddr(ip);
            sdkIdentifyResultPushLog.setParkCode(parkArmInfo.getParkCode());
            sdkIdentifyResultPushLog.setParkName(parkArmInfo.getParkName());
            sdkIdentifyResultPushLog.setSerialNo(parkArmInfo.getSerialNo());
            sdkIdentifyResultPushLog.setCreateTime(new Date());
            //车牌号
            sdkIdentifyResultPushLog.setLicense(license.trim());
            //识别时间
            sdkIdentifyResultPushLog.setNTime(byteArray2Int(ptImageInfo.acSnapTime));
            //车辆类型
            sdkIdentifyResultPushLog.setNType(convertType(ptImageInfo.ucLprType));
            //车辆颜色
            sdkIdentifyResultPushLog.setColor((int) ptImageInfo.ucVehicleColor);
            //方向
            sdkIdentifyResultPushLog.setNDirection((int) ptImageInfo.ucDirection);
            //车牌颜色
            sdkIdentifyResultPushLog.setNColor((int) ptImageInfo.ucPlateColor);
            //获得带图片的sdk对象
            saveImg(sdkIdentifyResultPushLog, ptPicInfo);
            //识别信息保存数据库
            sdkIdentifyResultPushLogService.save(sdkIdentifyResultPushLog);
            // 第三版出入场逻辑调用
            sdkIdentifyResultPushLogV3Service.identifyJudge(sdkIdentifyResultPushLog,parkArmInfo);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 保存本地图片以及阿里云图片并返回地址
     *
     * @param sdkIdentifyResultPushLog
     * @param ptPicInfo
     * @return com.jdd.modules.sdkidentifyresultpushlog.entity.SdkIdentifyResultPushLog
     * @author jdd孙庆伟
     * @date 2021/7/7 10:06:45
     * @version 1.0
     */
    public void saveImg(SdkIdentifyResultPushLog sdkIdentifyResultPushLog, QIANYISDK.T_PicInfo.ByReference ptPicInfo) {
        String ossImg = null;

        /* 保存抓拍图片*/
        Random random = new Random();
        String result = "";
        //随机生成6位随机数
        for (int i = 0; i < 6; i++) {
            result += random.nextInt(10);
        }
        //抓拍时间,每天一个文件夹
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;
        int day = instance.get(Calendar.DAY_OF_MONTH);

        //本地
        //文件夹名字生成规则请勿轻易更改，如果更改，请修改定时删除图片任务的文件夹名字的生成规则
        String imgUrl = imageLocation + "/" + year + "-" + month + "-" + day;
        File dir = new File(imgUrl);
        //判断目录是否存在不存在则新建
        if (!dir.exists()) {
            try {
                dir.mkdir();
            } catch (Exception e) {
                log.error("新建图片文件夹失败->{}", e);
            }
        }

        long timeMillis = System.currentTimeMillis();
        //图片存放路径
        //文件夹名字生成规则请勿轻易更改，如果更改，请修改定时删除图片任务的文件夹名字的生成规则
        String impart = imgUrl + File.separator  + timeMillis + result + ".jpeg";

        String urls = location + "/" + year + "-" + month + "-" + day + File.separator+ timeMillis + result + ".jpeg";

        sdkIdentifyResultPushLog.setImg(urls);

         getFileFromBytes(ptPicInfo.ptPanoramaPicBuff.getByteArray(0, ptPicInfo.uiPanoramaPicLen), impart);

        String getOssUrl = ossUtil.getImgUrl();

        sdkIdentifyResultPushLog.setOssImg(ossDomainName+getOssUrl);

        asynRestTmplateUtils.uploadOssImg(impart,getOssUrl);
    }



    /**
     * @param b
     * @return
     * @Description byte数组转换为整型
     * @author shangyue
     * @Date 2021/4/6
     */
    public static int byteArray2Int(byte[] b) {
        int value = 0;
        for (int i = b.length - 1; i >= 0; i--) {
            int shift = (b.length - 1 - i) * 8;
            value += (b[i] & 0x000000FF) << shift;
        }

        return value;
    }

    /**
     * 芊熠的车辆类型与数据库不一样，要转换成一致的
     *
     * @param type 芊熠识别出来的车辆类型
     * @return
     */
    public static int convertType(int type) {
        int result = type;
        switch (type) {
            case 7:
                result = 15;
                break;
            case 10:
                result = 7;
                break;
            //新能源小车
            case 11:
                result = 19;
                break;
            //新能源大车
            case 12:
                result = 19;
                break;
            //大使馆车牌
            case 13:
                result = 10;
                break;
            //领事馆车牌
            case 14:
                result = 10;
                break;
            case 15:
                result = 18;
                break;
            default:
                break;
        }
        return result;
    }

    /**
     * 将byte数据存为文件
     */
    public static File getFileFromBytes(byte[] b, String path) {
        BufferedOutputStream stream = null;
        File file = null;
        try {
            file = new File(path);
            FileOutputStream fstream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fstream);
            stream.write(b);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return file;
    }
}
